package com.bwie.service.impl;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bwie.mapper.MenuMapper;
import com.bwie.pojo.Menu;
import com.bwie.pojo.User;
import com.bwie.service.UserService;
import com.bwie.mapper.UserMapper;
import com.bwie.utils.MobileMessageUtil;
import com.bwie.utils.Result;
import com.bwie.vo.LoginForm;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
* @author 陈彤彤
* @description 针对表【t_user(用户表)】的数据库操作Service实现
* @createDate 2025-07-18 14:40:04
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{


    @Autowired
    UserMapper userMapper;

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    MenuMapper menuMapper;

    @Autowired
    HttpServletRequest request;

    /**
    * @param loginForm:
    * @return Result
    * @author :陈彤彤
    * @description 发送短信验证码
    * @date 2025/7/18 17:17
    */
    @Override
    public Result sendPhoneCode(LoginForm loginForm) {
        /*生成四位随机验证码*/
        String phoneCode = RandomUtil.randomNumbers(4);
        System.out.println("手机号验证码是：" + phoneCode);
        /*将验证码存入redis中*/
        redisTemplate.opsForValue().set(loginForm.getPhone(),phoneCode,5, TimeUnit.MINUTES);

        /*发送短信验证码*/
        Boolean aBoolean = MobileMessageUtil.sendMobileMessage(loginForm.getPhone(), phoneCode);
        return aBoolean ? Result.ok().setMsg("发送成功") : Result.error().setMsg("发送失败");
    }

    /**
    * @param loginForm:
    * @return Result
    * @author :陈彤彤
    * @description 手机号注册
    * @date 2025/7/18 17:19
    */
    @Override
    public Result userReg(LoginForm loginForm) {
        /*获取手机号key*/
        String phoneKey = loginForm.getPhone();
        String redisCode = redisTemplate.opsForValue().get(phoneKey);
        /*校验验证码*/
        if (redisCode == null){
            return Result.error().setMsg("验证码已过期");
        }
        if (!redisCode.equals(loginForm.getPhoneCode())){
            return Result.error().setMsg("验证码错误");
        }
        /*校验手机号是否存在*/
        User selectOne = userMapper.selectOne(new QueryWrapper<User>().lambda().eq(User::getPhone, loginForm.getPhone()));
        if (selectOne != null){
            return Result.error().setMsg("手机号信息已存在");
        }

        /*密码加密*/
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String hashPass = encoder.encode(loginForm.getPassword());
        System.out.println("加密密码是：" + hashPass);

        /*注册用户*/
        User user = new User();
        user.setPassword(hashPass);
        user.setPhone(loginForm.getPhone());
        user.setUsername("匿名用户");
        userMapper.insert(user);
        return Result.ok();
    }

    /**
    * @param loginForm:
    * @return Result
    * @author :陈彤彤
    * @description 手机号密码登录
    * @date 2025/7/18 17:28
    */
    @Override
    public Result phoneLogin(LoginForm loginForm) {
        /*1.查询用户信息*/
        User user = userMapper.selectOne(new QueryWrapper<User>().lambda().eq(User::getPhone, loginForm.getPhone()));
        if (user == null){
            return Result.error().setMsg("手机号不存在");
        }

        /*2.校验密码*/
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        boolean password = encoder.matches(loginForm.getPassword(), user.getPassword());

        if (!password){
            return Result.error().setMsg("密码错误");
        }

        /*3.生成token*/
        String token = Jwts.builder().signWith(SignatureAlgorithm.HS256, "123456").claim("userId", user.getUserId()).claim("username", user.getUsername()).compact();
        /*4.存入redis并设置存活时长*/
        String redisToken = "token-" + user.getUserId();
        redisTemplate.opsForValue().set(redisToken,token,60,TimeUnit.MINUTES);

        /*获取当前用户角色*/
        List<String> roleList = userMapper.getRoleListByUserId(user.getUserId());
        user.setRoleList(roleList);

        /*5.返回数据*/
        user.setToken(token);
        user.setPassword(null);
        return Result.ok().setData(user);
    }

    /**
    * @param :
    * @return Result
    * @author :陈彤彤
    * @description 获取用户动态菜单
    * @date 2025/7/20 20:37
    */
    @Override
    public Result menuList() {
        /*获取token*/
        String token = request.getHeader("token");
        if (token == null){
            return Result.error().setMsg("请先登录");
        }
        /*解析token*/
        Claims claims = Jwts.parser().setSigningKey("123456").parseClaimsJws(token).getBody();
        Integer userId = claims.get("userId", Integer.class);

        /*查询所有菜单信息*/
        List<Menu> list = menuMapper.menuList(userId);
        /*构造菜单树*/
        List<Tree<String>> treeList = TreeUtil.build(list, "0", (menu, tree) -> {
            tree.setId(menu.getId() + "");
            tree.setName(menu.getName() + "");
            tree.setParentId(menu.getPid() + "");

            tree.putExtra("path",menu.getPath());
        });

        return Result.ok().setData(treeList);
    }
}




